import json
from typing import Dict, Tuple
from pathlib import Path


class GradeManager:
    # 成绩数据管理

    def __init__(self, db_path: str = "grades.json"):
        self.db_path = Path(db_path)
        self._init_db()

    def _init_db(self):
        # 初始化数据库文件
        if not self.db_path.exists():
            with open(self.db_path, 'w') as f:
                json.dump({}, f)

    def _load_data(self) -> Dict:
        # 加载成绩数据
        with open(self.db_path, 'r') as f:
            data = json.load(f)
            return self._convert_old_format(data)

    def _convert_old_format(self, data: Dict) -> Dict:
        # 将旧数据格式转换为新格式
        new_data = {}
        for username, subjects in data.items():
            new_data[username] = {}
            for subject, value in subjects.items():
                if isinstance(value, dict):
                    new_data[username][subject] = value
                else:
                    new_data[username][subject] = {
                        "score": value,
                        "credit": 1.0
                    }
        return new_data

    def _save_data(self, data: Dict):
        # 保存成绩数据
        with open(self.db_path, 'w') as f:
            json.dump(data, f, indent=4)

    def update_grade(self, username: str, subject: str, score: float, credit: float) -> bool:
        # 更新或添加成绩
        data = self._load_data()
        if username not in data:
            data[username] = {}

        data[username][subject] = {
            "score": score,
            "credit": credit
        }
        self._save_data(data)
        return True

    def delete_grade(self, username: str, subject: str) -> bool:
        # 删除成绩
        data = self._load_data()
        if username not in data or subject not in data[username]:
            return False

        del data[username][subject]
        self._save_data(data)
        return True

    def get_grades(self, username: str) -> Dict[str, Dict[str, float]]:
        # 获取用户所有成绩
        data = self._load_data()
        return data.get(username, {})

    def calculate_weighted_average(self, username: str) -> Tuple[float, float]:
        # 计算加权平均分和总学分
        grades = self.get_grades(username)
        if not grades:
            return 0.0, 0.0

        total_score = 0.0
        total_credit = 0.0

        for info in grades.values():
            score = info.get('score', 0)
            credit = info.get('credit', 0)
            total_score += score * credit
            total_credit += credit

        return (total_score / total_credit if total_credit != 0 else 0.0,
                total_credit)